/*锟斤拷锟斤拷说锟斤拷薷姆锟斤拷锟斤拷锟�
 * 1.锟睫革拷头锟侥硷拷锟疥定锟斤拷row锟斤拷锟斤拷
 * 2.锟睫革拷info_found
 * 3.锟睫改讹拷锟斤拷锟剿碉拷指锟诫函锟斤拷锟斤拷锟斤拷
 * 4.锟斤拷锟斤拷锟接菜碉拷
 * 5.锟斤拷锟斤拷锟接菜碉拷锟斤拷锟斤拷头锟侥硷拷
 * 6.锟接菜碉拷锟斤拷锟睫革拷flash锟斤拷锟斤拷锟街�
 *
 *
 */
#include "zf_common_headfile.h"

unsigned char dananflag = 0;

// 判断是在选择参数菜单还是选择参数
bool menu_level = 0;

// 在选择参数菜单的光标位置,即当前选择调参菜单
unsigned char menu_index = 0;
// 显示字符串存储数组
char menustr[30];

// 判断是在选择参数还是修改参数
bool menu2_level = 0;

// 菜单属性信息
// 在选择参数的光标位置
unsigned char menu2_index = 0;
// 参数类型(int/float)
unsigned char menu2_mode = 0;
// 参数个数
unsigned char menu2_limit = 0;

// 调参幅值数组下标
char magindex = 0;
// 调参的幅值数组
float mag[] = { 100, 10, 1, 0.1, 0.01 };

// 指向该菜单界面参数的数组
int *intvalue[MAX_MENU2_NUM];
float *floatvalue[MAX_MENU2_NUM];

//在flash中写入的位置下标
unsigned char flash_index = 0;

//  菜单函数数组
void (*menu_pfc[]) (unsigned char) = { menu_select, menu2_select };

// 具体调参函数数组
char (*amenu2_init_pfc[]) (char) = {
        menu2_setting, \
        menu2_set_speed, \
        menu2_aim_distance, \
        menu2_servo_pid, \
        menu2_speed_pid_l, menu2_speed_pid_r, \
        menu2_target_speed
};

//KEY_1,  // 上
//KEY_2,  // 下
//KEY_3,  // 摁
//KEY_4,  // 右
//KEY_5,  // 左

// 光标向下,减数值 --> 下
// 减小幅值        --> 右
// 确认            --> 摁
// 增加幅值        --> 左
// 光标向上,加数值 --> 上

void menu_entry (void)
{
    key_scanner();

    // 向上短摁
    if (key_get_state(KEY_1) == KEY_SHORT_PRESS || dananflag == 1)
    {
        dananflag = 1;
        key_clear_state(KEY_1);
        if (key_get_state(KEY_1) == KEY_RELEASE)
        {
            menu_pfc[menu_level](1);
            dananflag = 0;
        }
    }

    // 向下短摁
    if (key_get_state(KEY_2) == KEY_SHORT_PRESS || dananflag == 2)
    {
        dananflag = 2;
        key_clear_state(KEY_2);
        if (key_get_state(KEY_2) == KEY_RELEASE)
        {
            menu_pfc[menu_level](2);
            dananflag = 0;
        }
    }

    // 短摁下
    if (key_get_state(KEY_3) == KEY_SHORT_PRESS || dananflag == 3)
    {
        dananflag = 3;
        key_clear_state(KEY_3);
        if (key_get_state(KEY_3) == KEY_RELEASE)
        {
            menu_pfc[menu_level](3);
            dananflag = 0;
        }
    }

    // 向右短摁
    if (key_get_state(KEY_4) == KEY_SHORT_PRESS || dananflag == 4)
    {
        dananflag = 4;
        key_clear_state(KEY_4);
        if (key_get_state(KEY_4) == KEY_RELEASE)
        {
            menu_pfc[menu_level](4);
            dananflag = 0;
        }
    }

    // 向左短摁
    if (key_get_state(KEY_5) == KEY_SHORT_PRESS || dananflag == 5)
    {
        dananflag = 5;
        key_clear_state(KEY_5);
        if (key_get_state(KEY_5) == KEY_RELEASE)
        {
            menu_pfc[menu_level](5);
            dananflag = 0;
        }
    }
}

void menu_select (unsigned char event)
{
    // menu_select在menu_pfc数组中下标为0,当通过menu_pfc调用该函数时,menu_level必为0
    if (!menu_level)
    {
        switch (event)
        {
        case 1 :
            // menu_select(1)光标向上移动或移动至末位
            if (menu_index > 0)
                menu_index--;
            else
                menu_index = ROWS - 1;
            break;
        case 2 :
            // menu_select(2)光标向下移动,或移动至首位
            if (menu_index < ROWS - 1)
                menu_index++;
            else
                menu_index = 0;
            break;
        case 3 :
            // 改变状态为选择参数模式
            menu_level = 1;
            // menu_select(3)确定进入该菜单调参
            menu2_init();
            return;
        }
    }
}

void menu2_init ()
{
    // 调参幅值数组下标至0
    magindex = 0;
    // 进入选择参数模式
    menu2_level = 0;
    // 选择光标位置
    menu2_index = 0;
    // 参数个数
    menu2_limit = 0;

    ips200_full(RGB565_WHITE);
}

// 修改数值
static void modify (unsigned char event)
{
    // 根据menu2_mode的值判断元素类型
    // 根据传入event确定数值加减
    switch (menu2_mode)
    {
    case PARASET_F :
        if (event)
            *floatvalue[menu2_index] += mag[magindex];
        else
            *floatvalue[menu2_index] -= mag[magindex];
        break;
    case PARASET_S :
        if (event)
            *intvalue[menu2_index] += mag[magindex];
        else
            *intvalue[menu2_index] -= mag[magindex];
        break;
    }
}

void menu2_select (unsigned char event)
{
    if (!menu2_level)
    {
        // 当前在选择参数
        switch (event)
        {
        case 1 :
            // menu2_select(1)光标向上移动
            if (menu2_index > 0)
                menu2_index--;
            break;
        case 2 :
            // menu2_select(2)光标向下移动
            if (menu2_index < menu2_limit)
                menu2_index++;
            break;
        case 3 :
            // menu2_select(3)选择该参数
            menu2_level = 1;
            break;
        }
    }
    else
    {
        // 当前在修改参数
        switch (event)
        {
        case 1 :
            // menu2_select(1)加当前幅值
            modify(1);
            break;
        case 2 :
            // menu2_select(2)减当前幅值
            modify(0);
            break;
        case 3 :
            // menu2_select(3)确认
            // 写入flash中
            flash_memory_write();
            // 回到选择参数状态
            menu2_level = 0;
            ips200_full(RGB565_WHITE);
            return;
        case 4 :
            // menu2_select(4)减小幅值
            magindex++;
            if (magindex >= sizeof(mag) / sizeof(mag[0]))
                magindex = 0;
            break;
        case 5 :
            // menu2_select(4)增大幅值
            magindex--;
            if (magindex < 0)
                magindex = 4;
            break;
        }
    }
}

void menu_display (void)
{
    register char i;
    if (!menu_level)
    {
        // 在选择参数菜单状态,一行行扫描
        for (i = 0; i < ROWS; i++)
        {
            // 光标所在位置背景颜色BLUE,其余为WHITE
            if (i == menu_index)
                ips200_bgcolor= RGB565_BLUE;
            else
                ips200_bgcolor= RGB565_WHITE;
            // 将当前显示字符串写入menustr中并显示
            info_found(i);
            ips200_show_string(0, i, menustr);
        }
    }
}

void menu2_display (void)
{
    unsigned char i;
    // 在该位置显示调参幅度
    ips200_show_float(150, 14, mag[magindex] + 0.001, 3, 2);
    for (i = 0; i <= menu2_limit; i++)
    {
        // 在调参菜单状态,一行行扫描
        // 根据当前调参菜单的光标位置调用对应的调参菜单,拷贝显示字符串进menustr
        amenu2_init_pfc[menu_index](i);
        if (!menu2_level)
        {
            // 当前状态为选择参数
            // 光标所在位置背景颜色BLUE,其余为WHITE
            if (menu2_index == i)
                ips200_bgcolor= RGB565_BLUE;
            else
                ips200_bgcolor= RGB565_WHITE;
            // 将当前显示字符串写入menustr中并显示
            ips200_show_string(0, i, menustr);
        }
        else
        {
            // 当前状态为调参
            // 根据menu2_mode中设置状态,调用不同显示方式
            if (menu2_mode == PARASET_S)
                ips200_show_int(150, menu2_index, *intvalue[menu2_index], 4);
            else
                ips200_show_float(150, menu2_index, *floatvalue[menu2_index], 4, 2);
        }
    }
    // 当前选择参数的光标位置移动到参数边界,即最后一个选项exit
    if (menu2_index == menu2_limit)
    {
        // 切换状态从调整参数至选择参数
        menu_level = 0;
        ips200_full(RGB565_WHITE);
    }
}

// 调参函数的显示查找
void info_found (unsigned char index)
{
    // 清空menustr
    memset(menustr, 0, sizeof menustr);
    // 根据index向menustr中拷贝不同字符串以显示
    switch (index)
    {
    case 0 :
        strcpy(menustr, "setting");
        break;
    case 1 :
        strcpy(menustr, "speed");
        break;
    case 2 :
        strcpy(menustr, "aim_distance");
        break;
    case 3 :
        strcpy(menustr, "servo_pid");
        break;
    case 4 :
        strcpy(menustr, "speed_pid_l");
        break;
    case 5 :
        strcpy(menustr, "speed_pid_r");
        break;
    case 6 :
        strcpy(menustr, "motor_target_speed");
        break;
    }
}

// 调参菜单

// 设置菜单
char menu2_setting (char index)
{
    // 参数类型为int
    menu2_mode = PARASET_S;
    // 设置参数个数
    menu2_limit = 3;
    // 将参数添加进调参数组中
    intvalue[0] = (int*)(&init_value);
    intvalue[1] = (int*)(&motor_test);
    intvalue[2] = (int*)(&rampway_flag);
    // 设置写入flash位置
    flash_index = 0;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "init_value");
        return 0;
    case 1 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "motor_test");
        return 0;
    case 2 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "rampway_flag");
        return 0;
    case 3 :
        // 最后一个选项固定exit
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "exit");
        return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_S;
        return menu2_limit;
    }
    return 0;
}

// speed菜单
char menu2_set_speed (char index)
{
    // 参数类型为int
    menu2_mode = PARASET_S;
    // 设置参数个数
    menu2_limit = 5;
    // 将参数添加进调参数组中
    intvalue[0] = (int*)(&set_speed_flash);
    intvalue[1] = (int*)(&bend_set_speed_flash);
    intvalue[2] = (int*)(&circle_set_speed_flash);
    intvalue[3] = (int*)(&cross_set_speed_flash);
    intvalue[4] = (int*)(&ramp_set_speed_flash);
    // 设置写入flash位置
    flash_index = 1;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "set_speed");
        return 0;
    case 1 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "bend_set_speed");
        return 0;
    case 2 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "circle_set_speed");
        return 0;
    case 3 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "cross_set_speed");
        return 0;
    case 4 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "ramp_set_speed");
        return 0;
    case 5 :
        // 最后一个选项固定exit
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "exit");
        return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_S;
        return menu2_limit;
    }
    return 0;
}

// 预瞄点菜单
char menu2_aim_distance(char index)
{
    // 参数类型为float
    menu2_mode = PARASET_F;
    // 设置参数个数
    menu2_limit = 6;
    // 将参数添加进调参数组中
    floatvalue[0] = &aim_distance_flash;
    floatvalue[1] = (float*)&bend_check_aim_distance;
    floatvalue[2] = (float*)&bend_aim_distance_flash;
    floatvalue[3] = (float*)&circle_aim_distance_flash;
    floatvalue[4] = (float*)&cross_aim_distance_flash;
    floatvalue[5] = (float*)&stop_aim_distance;
    // 设置写入flash位置
    flash_index = 2;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "aim_distance");
        return 0;
    case 1 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "bend_check_aim");
        return 0;
    case 2 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "bend_aim");
        return 0;
    case 3 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "circle_aim");
        return 0;
    case 4 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "cross_aim");
        return 0;
    case 5 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "stop_aim");
        return 0;
    case 6 :
        // 最后一个选项固定exit
       memset(menustr, 0, sizeof menustr);
       strcpy(menustr, "exit");
       return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_F;
        return menu2_limit;
    }
    return 0;
}

// 方向环pid菜单
char menu2_servo_pid (char index)
{
    // 参数类型为float
    menu2_mode = PARASET_F;
    // 设置参数个数
    menu2_limit = 4;
    // 将参数添加进调参数组中
    floatvalue[0] = &servo_pid.kp;
    floatvalue[1] = &servo_pid.ki;
    floatvalue[2] = &servo_pid.kd;
    floatvalue[3] = &imu_servo_coefficient;
    // 设置写入flash位置
    flash_index = 3;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "servo_kp");
        return 0;
    case 1 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "servo_ki");
        return 0;
    case 2 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "servo_kd");
        return 0;
    case 3 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "imu_servo_coe");
        return 0;
    case 4 :
        // 最后一个选项固定exit
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "exit");
        return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_F;
        return menu2_limit;
    }
    return 0;
}

// 左轮电机pid菜单
char menu2_speed_pid_l (char index)
{
    // 参数类型为float
    menu2_mode = PARASET_F;
    // 设置参数个数
    menu2_limit = 3;
    // 将参数添加进调参数组中
    floatvalue[0] = &motor_pid_l.kp;
    floatvalue[1] = &motor_pid_l.ki;
    floatvalue[2] = &motor_pid_l.kd;
    // 设置写入flash位置
    flash_index = 4;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "speed_kp");
        return 0;
    case 1 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "speed_ki");
        return 0;
    case 2 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "speed_kd");
        return 0;
    case 3 :
        // 最后一个选项固定exit
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "exit");
        return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_F;
        return menu2_limit;
    }
    return 0;
}

// 右轮电机pid菜单
char menu2_speed_pid_r (char index)
{
    // 参数类型为float
    menu2_mode = PARASET_F;
    // 设置参数个数
    menu2_limit = 3;
    // 将参数添加进调参数组中
    floatvalue[0] = &motor_pid_r.kp;
    floatvalue[1] = &motor_pid_r.ki;
    floatvalue[2] = &motor_pid_r.kd;
    // 设置写入flash位置
    flash_index = 5;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "speed_kp");
        return 0;
    case 1 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "speed_ki");
        return 0;
    case 2 :
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "speed_kd");
        return 0;
    case 3 :
        // 最后一个选项固定exit
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "exit");
        return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_F;
        return menu2_limit;
    }
    return 0;
}

// 电机调试速度菜单
char menu2_target_speed (char index)
{
    // 参数类型为int
    menu2_mode = PARASET_S;
    // 设置参数个数
    menu2_limit = 1;
    // 将参数添加进调参数组中
    intvalue[0] = (int*)(&pid_target_speed);
    // 设置写入flash位置
    flash_index = 6;
    switch (index)
    {
    case 0 :
        // 拷贝显示字符串进menustr
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "pid_target_speed");
        return 0;
    case 1 :
        // 最后一个选项固定exit
        memset(menustr, 0, sizeof menustr);
        strcpy(menustr, "exit");
        return 0;
    case FLASH_INIT :
        // 获取该函数中参数的类型,并返回参数个数
        menu2_mode = PARASET_S;
        return menu2_limit;
    }
    return 0;
}
